function  $(pieces, ...args) {
    let cmd = pieces[0], i = 0
    while (i < args.length) {
        let s
        if (Array.isArray(args[i])) {
            s = args[i].map((x) => $.quote(substitute(x))).join(' ')
        } else {
            s = $.quote(substitute(args[i]))
        }
        cmd += s + pieces[++i]
    }
    let resolve, reject
    let promise = new ProcessPromise((...args) => ([resolve, reject] = args))
    promise._bind(cmd, new Error(), resolve, reject, getStore())
    setImmediate(() => promise._run())
    return promise
}
function substitute(arg) {
    if (arg?.stdout) arg.stdout.replace(/\n$/, '')
    return `${arg}`
}
function quote(arg) {
    if (/^[a-z0-9/_.-]+$/i.test(arg) || arg === '') return arg
    return `$'` + arg.replace(/\\/g, '\\\\').replace(/\0/g, '\\0') +`'`
}

import { spawn } from 'child_process'
class ProcessPromise extends Promise {
    get stdin(){
        this._run()
        return this.child.stdin
    }
    get stdout(){
        this._run()
        return this.child.stdout
    }
    get stderr(){
        this._run()
        return this.child.stderr
    }
    _bind(){
        this._command = cmd
        this._from = from
        this._resolve = resolve
        this._reject = reject
        this._snapshot = { shell,cwd,spawn,quote }
    }
    _run() {
        const $ = this._snapshot
        this.child = $.spawn($.prefix + this._command, {
            cwd: $.cwd ?? $[processCwd],
            shell: typeof $.shell === 'string' ? $.shell : true,
            stdio: this._stdio,
            windowsHide: true,
            env: $.env,
        })
        this.child.on('close', () => {})
        this.child.on('error',()=>{})
    }
}

